知られたくないドメインのSSL/TLS証明書を取得する場合は証明書の透明性(CT)を無効にしよう(AWS Certificate Manager編)
SSL/TLS証明書(以下証明書)には証明書の監視や監査を行って証明書の信頼性を高める「Certificate Transparency(証明書の透明性;以下CT)」という仕組みがあります。
Certificate Transparency : Certificate Transparency
CAが証明書を発行する際には、パブリックなCTログサーバーに発行履歴を登録し、ログサーバーから受け取った署名付きのタイムスタンプ(SCT;Signed Certificate Timestamp)を埋め込んだ証明書を発行します(埋め込まない方法も有り)。
ブラウザは証明書に埋め込まれたSCTを確認し、存在しなければ証明書を不正とみなします(ブラウザによります)。
また、CAやドメイン管理者にとっては、CTログサーバーを監視することで、不正に発行された証明書を早期に検知できます。
※図は https://certificate.transparency.dev/howctworks/ から
試しに dev.classmethod.jp の証明書の SCT を確認してみましょう。
Embedded Signed Certificate Timestamp List の Log Operator から
- DigiCert
- Cloudflare
の SCT が含まれていることがわかります。
このフレームワークは rfc6962 : Certificate Transparency で標準化されています。
CT はその透明性ゆえ、証明書発行の不正利用の早期検知に役に立つ一方で、公にしたくないドメインを公開してしまう問題もはらんでいます。
本記事では、AWS Certificate Manager(ACM)で証明書を取得する時に、CTを無効化する方法をご紹介します。
CT のメリット
ドメインの所有者やCAの場合、CTログから不正な証明書が発行されていないか監視する事ができます。
例えば、Cloudflare には CT Monitoring というサービスが存在し、CTログで保有ドメインに対する証明書発行のログを検知すると、通知することができます。
また、サイトにアクセスする一般利用者の場合、SCTの存在しない証明書を怪しいと判断することができます。
CT のデメリット
一方で、CT にはデメリットもあります。
CTはその透明性(transparency)の仕組みから、発行された証明書がパブリックな CT ログサーバーに登録されます。
例えば、新規サービス向けにサブドメインを割り当て、その証明書を取得すると、そのサブドメインが漏洩してしまいます。
CT ログオペレーターの Google は、証明書をホスト名で検索するサービスも提供しています。
試しに example.com の証明書をサブドメインも含めて検索してみましょう。
www.example.com など、サブドメイン含め、取得された証明書を簡単に閲覧できます。
Chrome(Edge含む)などのブラウザは SCT ログのない証明書を不正とみなすため、主要CAはCTログをデフォルトで登録します。
以下では、ACM(AWS Certificate Manager)で証明書を取得する際に、ホスト名がCTログサーバーに登録されないよう、CTを無効化する方法を紹介します。
ACM(AWS Certificate Manager)でCTログをオプトアウトするには?
AWSの証明書を発行するサービス ACM は CTログをオプトアウトさせることができます。
ACM のベストプラクティスドキュメントに、CT(証明書の透明性)ログの潜在リスクとオプトアウトする方法が記載されています。
証明書の透明性ログ記録のオプトアウト
...(中略) ログ記録は、証明書をリクエストするとき、または証明書が更新されたときに自動的に実行されますが、オプトアウトすることもできます。その一般的な理由には、セキュリティとプライバシーに関する懸念があります。たとえば、内部ホストドメイン名のログ記録により、それ以外の場合には公開されない内部ネットワークについての情報が潜在的な攻撃者に提供されます。さらに、ログ記録により、新規または未リリース製品やウェブサイトの名前が漏洩する可能性があります。
証明書をリクエストするときに、透明性ログを出力しないようにするには、request-certificate AWS CLIコマンド、または RequestCertificateAPI オペレーションの options パラメータを使用します。証明書が 2018 年 4 月 24 日より前に発行され、更新中にログに記録されないようにする場合は、 コマンド、または UpdateCertificateOptions API オペレーションを使用してオプトアウトすることができます。
ACM でCTログをオプトアウトしてみる
CTログのオプトアウトはコンソールからは選択できないため、AWS CLIまたは SDK で acm request-certificate
API を呼び出します。
ポイントは オプションで CertificateTransparencyLoggingPreference=DISABLED
を渡すことです。
$ aws acm request-certificate \ --domain-name sct.example.com \ --validation-method DNS \ --options CertificateTransparencyLoggingPreference=DISABLED { "CertificateArn": "arn:aws:acm:us-east-1:123:certificate/xxx-xxx-xxx-xxx-xxx" }
CTを無効にした証明書をサーバーに適用し、Chrome からアクセスしてみましょう。
ChromeはSCTが存在しない証明書を不正とみなすため、NET::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED
エラーが発生しました。
CT を考案したGoogle 謹製の SCT チェックツールでコマンドラインからも SCT を検証してみましょう。
$ go install github.com/google/certificate-transparency-go/ctutil/sctcheck@latest $ sctcheck --logtostderr https://sct.example.co/ I1218 13:10:28.036546 1178 sctcheck.go:164] Retrieve certificate chain from TLS connection to "sct.example.co:443" I1218 13:10:28.063165 1178 sctcheck.go:177] Found chain of length 4 E1218 13:10:28.064150 1178 sctcheck.go:78] Found 0 external SCTs for "https://sct.example.co/", of which 0 were validated E1218 13:10:28.064164 1178 sctcheck.go:99] Found 0 embedded SCTs for "https://sct.example.co/", of which 0 were validated
証明書に対応する SCT が存在しないことがわかります。
比較のために、SCT を含んだ証明書への実行ログも共有します。
$ sctcheck --logtostderr https://dev.classmethod.jp I1218 08:35:34.272440 3509 sctcheck.go:164] Retrieve certificate chain from TLS connection to "dev.classmethod.jp:443" I1218 08:35:34.940379 3509 sctcheck.go:177] Found chain of length 4 E1218 08:35:34.940993 3509 sctcheck.go:78] Found 0 external SCTs for "https://dev.classmethod.jp", of which 0 were validated I1218 08:35:34.941130 3509 sctcheck.go:222] Examine embedded SCT[0] with timestamp: 1620519588587 (2021-05-09 00:19:48.587 +0000 UTC) from logID: 2979bef09e393921f056739f63a577e5be577d9c600af8f94d5d265c255dc7 84 I1218 08:35:34.941272 3509 sctcheck.go:235] Validate embedded SCT[0] against log "Google 'Argon2022' log"... I1218 08:35:34.941449 3509 sctcheck.go:240] Validate embedded SCT[0] against log "Google 'Argon2022' log"... validated I1218 08:35:34.941465 3509 sctcheck.go:244] Check embedded SCT[0] inclusion against log "Google 'Argon2022' log"... I1218 08:35:35.304628 3509 sctcheck.go:255] Check embedded SCT[0] inclusion against log "Google 'Argon2022' log"... included at 41353849 I1218 08:35:35.304740 3509 sctcheck.go:222] Examine embedded SCT[1] with timestamp: 1620519587561 (2021-05-09 00:19:47.561 +0000 UTC) from logID: 2245450759552456963fa12ff1f76d86e0232663adc04b7f5dc6835c6ee20f 02 I1218 08:35:35.304875 3509 sctcheck.go:235] Validate embedded SCT[1] against log "DigiCert Yeti2022 Log"... I1218 08:35:35.305039 3509 sctcheck.go:240] Validate embedded SCT[1] against log "DigiCert Yeti2022 Log"... validated I1218 08:35:35.305072 3509 sctcheck.go:244] Check embedded SCT[1] inclusion against log "DigiCert Yeti2022 Log"... I1218 08:35:36.053546 3509 sctcheck.go:255] Check embedded SCT[1] inclusion against log "DigiCert Yeti2022 Log"... included at 42240070 I1218 08:35:36.053736 3509 sctcheck.go:222] Examine embedded SCT[2] with timestamp: 1620519588564 (2021-05-09 00:19:48.564 +0000 UTC) from logID: 41c8cab1df22464a10c6a13a0942875e4e318b1b03ebeb4bc768f090629606 f6 I1218 08:35:36.053823 3509 sctcheck.go:235] Validate embedded SCT[2] against log "Cloudflare 'Nimbus2022' Log"... I1218 08:35:36.053985 3509 sctcheck.go:240] Validate embedded SCT[2] against log "Cloudflare 'Nimbus2022' Log"... validatedI1218 08:35:36.054008 3509 sctcheck.go:244] Check embedded SCT[2] inclusion against log "Cloudflare 'Nimbus2022' Log"... I1218 08:35:36.612876 3509 sctcheck.go:255] Check embedded SCT[2] inclusion against log "Cloudflare 'Nimbus2022' Log"... included at 40019104 E1218 08:35:36.612911 3509 sctcheck.go:99] Found 3 embedded SCTs for "https://dev.classmethod.jp", of which 3 were validated
- Google Argon
- DigiCert Yeti
- Cloudflare Nimbus
へのログ登録を確認できます。
CTを無効にする場合、SCT検証をしないブラウザを推奨したり、Chrome/Edge のようにSCT検証をするブラウザにも対応するのであれば、次のURLのように対象ドメインに対して CertificateTransparencyEnforcementDisabledForUrls
ポリシーでCTチェックを無効化できます。
Chrome Enterprise Policy List & Management | Documentation
既存の ACM 証明書の CT ログオプションを変更
acm::update-certificate-options
API を利用すると、CTログオプションを変更できます。
試しに、オプトイン(有効化)します。
$ aws acm update-certificate-options \ --certificate-arn arn:aws:acm:us-east-1:123:certificate/xxx-yyy-zzz-aaa \ --options CertificateTransparencyLoggingPreference=ENABLED $
ただし、この操作には問題があります。
CTログを無効化しても、過去の登録済みのCTログを削除することはできません。
また、CTログを有効化しても、CTログが登録されるのは、証明書を更新(=発行)するタイミングです。 SCTを埋め込んだ証明書が即座に必要な場合、CTログを有効にした証明書を新規に取得してください。
最後に
TLS/SSL証明書には、証明書の発行状況を監視・監査する証明書の透明性(Certificate Transparency/CT)という仕組みがあります。
CTを活用することで、意図せず発行された証明書を早期に検知できることが期待されます。 一方で、CTの透明性故、公開したくないドメイン情報が漏洩してしまうリスクもあります。
漏洩を避けたい場合は、ワイルドカード証明書を発行したり、CTログを無効にした証明書を発行してください。
後者の場合、ドメインがパブリックにならない一方で、Chrome のように証明書のSCTを検証するブラウザからはアクセスできなくなります。
SCT検証しないブラウザを利用したり、Chromeに対して特定のドメインをCTチェックから除外するポリシーを追加してください。
それでは。